Contents

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import numpy as np

from plotly.offline import init_notebook_mode
init_notebook_mode()

# Load and preprocess data
df = pd.read_csv('../data/capture_fisheries.csv', skiprows=4)
df = df.dropna(how='all')

# Clean data
df['Country Name'] = df['Country Name'].str.replace('"', '')
years = [str(year) for year in range(1960, 2025)]
id_vars = ["Country Name", "Country Code", "Indicator Name", "Indicator Code"]

# Melt data
df_melted = df.melt(id_vars=id_vars, value_vars=years, 
                   var_name="Year", value_name="Production")
df_melted['Year'] = pd.to_numeric(df_melted['Year'])
df_melted['Production'] = pd.to_numeric(df_melted['Production'], errors='coerce')
df_melted = df_melted.dropna(subset=['Production'])

# Calculate focused range (exclude extreme outliers)
q95 = df_melted['Production'].quantile(0.95)
focused_data = df_melted[df_melted['Production'] <= q95]
zmax = focused_data['Production'].max()
zmin = focused_data['Production'].min()

# Enhanced color scale with more distinction
enhanced_scale = [
    [0.0, '#E1F5FE'],  # Darkest purple
    [0.1, '#B3E5FC'],  # Deep purple
    [0.2, '#81D4FA'],  # Purple
    [0.3, '#4FC3F7'],  # Magenta
    [0.4, '#29B6F6'],  # Pink
    [0.5, '#039BE5'],  # Red
    [0.6, '#0288D1'],  # Orange-red
    [0.7, '#0277BD'],  # Orange
    [0.8, '#01579B'],  # Light orange
    [0.9, '#0D47A1'],  # Pale yellow
    [1.0, '#1d1c47']   # White
]

# 1. Static map showing total production (with focused scale)
total_production = df_melted.groupby(['Country Name', 'Country Code'])['Production'].sum().reset_index()

fig_total = px.choropleth(total_production,
                        locations="Country Code",
                        color="Production",
                        hover_name="Country Name",
                        color_continuous_scale=enhanced_scale,
                        range_color=[zmin, zmax],
                        title="<b>Total Fisheries Production (95% Range Focused)</b>",
                        labels={'Production': 'Production (metric tons)'},
                        projection="natural earth")

fig_total.update_layout(
    geo=dict(
        landcolor='#f0f0f0',
        lakecolor='#d0e0f0',
        bgcolor='white',
        showframe=True,
        framecolor='black'
    ),
    coloraxis_colorbar=dict(
        title="Production",
        thickness=20,
        len=0.75,
        tickvals=np.linspace(zmin, zmax, 6),
        ticktext=[f"{int(x):,}" for x in np.linspace(zmin, zmax, 6)]
    ),
    margin={"r":0,"t":60,"l":0,"b":0}
)

# 2. Interactive map with year slider - with better color distribution
frames = []
for year in sorted(df_melted['Year'].unique()):
    yearly_data = df_melted[df_melted['Year'] == year]
    yearly_focused = yearly_data[yearly_data['Production'] <= yearly_data['Production'].quantile(0.95)]
    year_zmax = yearly_focused['Production'].max()
    year_zmin = yearly_focused['Production'].min()
    
    frames.append(go.Frame(
        data=[go.Choropleth(
            locations=yearly_data['Country Code'],
            z=yearly_data['Production'],
            zmin=year_zmin,
            zmax=year_zmax,
            colorscale=enhanced_scale,
            customdata=yearly_data[['Country Name']],
            hovertemplate="<b>%{customdata[0]}</b><br>" +
                         "Year: %{frame.name}<br>" +
                         "Production: %{z:,} metric tons<extra></extra>",
            marker_line_color='darkgray',
            marker_line_width=0.5
        )],
        name=str(year)
    ))

# Create base figure
fig_slider = go.Figure(
    data=[go.Choropleth(
        locations=df_melted['Country Code'],
        z=df_melted['Production'],
        colorscale=enhanced_scale,
        customdata=df_melted[['Country Name']],
        hovertemplate="<b>%{customdata[0]}</b><br>" +
                     "Year: %{frame.name}<br>" +
                     "Production: %{z:,} metric tons<extra></extra>",
        marker_line_color='darkgray',
        marker_line_width=0.5
    )],
    layout=go.Layout(
        title="<b>Annual Fisheries Production with Enhanced Color Distinction</b>",
        geo=dict(
            showframe=True,
            showcoastlines=True,
            landcolor='#f0f0f0',
            lakecolor='#d0e0f0',
            bgcolor='white',
            framecolor='black',
            framewidth=1
        ),
        sliders=[{
            "active": 0,
            "steps": [{
                "args": [[f.name], {"frame": {"duration": 300, "redraw": True},
                                  "mode": "immediate"}],
                "label": f.name,
                "method": "animate"
            } for f in frames],
            "x": 0.1,
            "len": 0.9,
            "currentvalue": {
                "prefix": "<b>Year: </b>",
                "font": {"size": 14},
                "xanchor": "center"
            }
        }],
        updatemenus=[{
            "buttons": [
                {
                    "args": [None, {"frame": {"duration": 500, "redraw": True},
                                  "fromcurrent": True}],
                    "label": "▶️ Play",
                    "method": "animate"
                },
                {
                    "args": [[None], {"frame": {"duration": 0, "redraw": True},
                                    "mode": "immediate"}],
                    "label": "⏸️ Pause",
                    "method": "animate"
                }
            ],
            "type": "buttons",
            "x": 0.1,
            "y": 0,
            "bgcolor": "rgba(255,255,255,0.8)",
            "bordercolor": "#444"
        }]
    ),
    frames=frames
)

# Add explanatory annotation
fig_slider.add_annotation(
    x=0.5,
    y=-0.1,
    xref="paper",
    yref="paper",
    text="Color scale automatically focuses on 95% of data range for each year",
    showarrow=False,
    font=dict(size=12, color="#444")
)

fig_total.show()
fig_slider.show()